﻿using System;
using System.Diagnostics;
using System.Threading;

namespace HK.Core.Threader.Protocol
{
    /// <summary>
    /// 线程执行操作前预处理委托定义
    /// </summary>
    /// <returns>true:待机，进入睡眠状态; false:中止待机，继续向下执行;</returns>
    public delegate bool ThreadPrevOperation();
    
    /// <summary>
    /// 线程执行操作委托定义
    /// </summary>
    /// <returns>true:执行成功; false:执行失败;</returns>
    public delegate bool ThreadCurOperation();
    
    /// <summary>
    /// 线程完成操作后的处理委托定义
    /// </summary>
    /// <param name="iSucceed">执行成功标志位</param>
    /// <returns>true:继续执行; false:不用继续执行;</returns>
    public delegate bool ThreadNextOperation(bool iSucceed);
    
    /// <summary>
    /// 接口 : 线程执行器
    /// </summary>
    public interface IThreader : IDisposable
    {
        /// <summary>
        /// 线程ID
        /// </summary>
        int ThreadId { get; }
        
        /// <summary>
        /// 线程名
        /// </summary>
        string ThreadName { get; }
        
        /// <summary>
        /// 初始化标志位
        /// </summary>
        bool Initialized { get; }
        
        /// <summary>
        /// 有效标志位
        /// </summary>
        bool Valid { get; }
        
        /// <summary>
        /// 时间监控器
        /// </summary>
        Stopwatch TimeWatch { get; }
        
        /// <summary>
        /// 线程执行者
        /// </summary>
        Thread Executor { get; }
        
        /// <summary>
        /// 权限
        /// </summary>
        ThreadPriority Priority { get; }
        
        /// <summary>
        /// 消耗时间
        /// <para>* 单位：毫秒</para>
        /// </summary>
        long CostTime { get; }
        
        /// <summary>
        /// 执行中
        /// </summary>
        bool Executing { get; }
        
        /// <summary>
        /// 睡眠待机标志位
        /// <para>* 该线程会挂起，睡眠等待一定时间间隔后，在次启动。即:SleepInterrupt</para>
        /// <para>* true : 可以开始运行</para>
        /// <para>* false : 待机100毫秒后，继续执行</para>
        /// </summary>
        bool Sleeping { get; }
        
        /// <summary>
        /// 睡眠挂起等待时间间隔
        /// <para>* 单位:毫秒(默认:500毫秒)</para>
        /// </summary>
        int SleepInterrupt { get; }
        
        /// <summary>
        /// 已激活标志位
        /// </summary>
        bool Activated { get; }
        
        /// <summary>
        /// 停止标志位
        /// </summary>
        bool Stopped { get; }
        
        /// <summary>
        /// 成功标志位
        /// </summary>
        bool Succeeded { get; }

        /// <summary>
        /// 取得线程执行器名
        /// </summary>
        /// <returns>线程执行器名</returns>
        string GetThreaderName();

#region Step - Prev

        /// <summary>
        /// 执行前预处理
        /// <para>* 挂起睡眠等待时间间隔，默认值:500毫秒</para>
        /// </summary>
        ThreadPrevOperation PrevOperation { get; }

#endregion

#region Step - Current
        
        /// <summary>
        /// 线程当前处理
        /// </summary>
        ThreadCurOperation CurOperation { get; }

#endregion

#region Step - Next
        
        /// <summary>
        /// 执行后处理
        /// </summary>
        ThreadNextOperation NextOperation { get; }

#endregion
        
        /// <summary>
        /// 执行
        /// </summary>
        void Execute();
        
        /// <summary>
        /// 暂停标志位
        /// </summary>
        bool Paused { get; }

        /// <summary>
        /// 暂停
        /// </summary>
        void Pause();

        /// <summary>
        /// 恢复
        /// </summary>
        void Resume();

        /// <summary>
        /// 取消标志位
        /// <para>* 即便当前有任务在执行中，也中断</para>
        /// </summary>
        bool Canceled { get; }

        /// <summary>
        /// 取消
        /// </summary>
        void Cancel();
        
        /// <summary>
        /// 中断标志位
        /// <para>* 执行中断，但是尚未完全停下来</para>
        /// <para>* 若当前任务执行中，则等待执行完毕再中断</para>
        /// </summary>
        bool Interrupted { get; }

        /// <summary>
        /// 停止
        /// <para>* 若当前有任务在执行中，则当代任务执行完毕再</para>
        /// </summary>
        void Stop();

        /// <summary>
        /// 中止线程
        /// </summary>
        void Abort();
        
    }
}
